/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jsf;

import entidades.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import javax.faces.FacesException;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.event.ValueChangeEvent;
import javax.faces.model.SelectItem;
import javax.faces.validator.ValidatorException;
import jpa.*;
import jsf.util.JsfUtil;
import jpa.exceptions.NonexistentEntityException;


/**
 *
 * @author dvasquez
 */
public class FormularioController {

    public FormularioController() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        dcdJpa = (DensidadesConDensimetroJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "densidadesConDensimetroJpa");
        infDcdJpa = (InformeReferenciaDCDJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "informeReferenciaDCDJpa");
        puntoDcdJpa = (PuntoDCDJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "puntoDCDJpa");

        tmsJpa = (TomaMuestraSueloJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "tomaMuestraSueloJpa");

        masfJpa = (MuestreoAsfaltoJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "muestreoAsfaltoJpa");

        ctrJpa = (ControlTasaRiegoJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "controlTasaRiegoJpa");
        medCtrJpa= (MedicionesCTRJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "medicionesCTRJpa");

        ctempJpa = (ControlTemperaturaJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "controlTemperaturaJpa");
        medCTJpa = (MedicionesCTJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "medicionesCTJpa");

        dcasfJpa = (DensidadesCarpetaAsfalticaJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "densidadesCarpetaAsfalticaJpa");
        medDcasfJpa = (MedicionesDCAsJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "medicionesDCAsJpa");

        dcarenaJpa = (DensidadesConoArenaJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "densidadesConoArenaJpa");
        infRefDCArJpa = (InformeReferenciaDCArJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "informeReferenciaDCArJpa");
        puntoDCArJpa = (PuntoDCArJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "puntoDCArJpa");

        hiloJpa = (HiloJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "hiloJpa");
        medHiloJpa = (MedicionesHiloJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "medicionesHiloJpa");

        marshallJpa = (MarshallControlJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "marshallControlJpa");

        tmhJpa = (TomaMuestraHormigonJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "tomaMuestraHormigonJpa");
        nromoldesJpa = (NroMoldesJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "nroMoldesJpa");
        antehormJpa = (AntecedentesHormigonJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "antecedentesHormigonJpa");
        mathormJpa = (MaterialesHormigonJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "materialesHormigonJpa");
        rupmoldesJpa = (RupturaMoldesJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "rupturaMoldesJpa");

        jpaController = (FormularioJpaController) facesContext.getApplication().getELResolver().getValue(facesContext.getELContext(), null, "formularioJpa");
        converter = new FormularioConverter();
    }
    private Formulario formulario = null;
    private List<Formulario> formularioItems = null;
    private FormularioJpaController jpaController = null;
    private FormularioConverter converter = null;
    private List Ensayos;

    private DensidadesConDensimetro dcd = null;
    private DensidadesConDensimetroJpaController dcdJpa;

    private List<InformeReferenciaDCD> infDcd = null;
    private InformeReferenciaDCDJpaController infDcdJpa;

    private List<PuntoDCD> puntoDcd = null;
    private PuntoDCDJpaController puntoDcdJpa;

    private TomaMuestraSuelo tms = null;
    private TomaMuestraSueloJpaController tmsJpa;

    private MuestreoAsfalto masf = null;
    private MuestreoAsfaltoJpaController masfJpa;

    private ControlTasaRiego ctr = null;
    private ControlTasaRiegoJpaController ctrJpa;

    private List<MedicionesCTR> medCtr = null;
    private MedicionesCTRJpaController medCtrJpa;

    private ControlTemperatura ctemp = null;
    private ControlTemperaturaJpaController ctempJpa;

    private List<MedicionesCT> medCT = null;
    private MedicionesCTJpaController medCTJpa;

    private DensidadesCarpetaAsfaltica dcasf = null;
    private DensidadesCarpetaAsfalticaJpaController dcasfJpa;

    private List<MedicionesDCAs> medDcasf = null;
    private MedicionesDCAsJpaController medDcasfJpa;

    private DensidadesConoArena dcarena = null;
    private DensidadesConoArenaJpaController dcarenaJpa;

    private List<InformeReferenciaDCAr> infRefDCAr = null;
    private InformeReferenciaDCArJpaController infRefDCArJpa;

    private List<PuntoDCAr> puntoDCAr = null;
    private PuntoDCArJpaController puntoDCArJpa;

    private Hilo hilo = null;
    private HiloJpaController hiloJpa;

    private List<MedicionesHilo> medHilo = null;
    private MedicionesHiloJpaController medHiloJpa;

    private MarshallControl marshall = null;
    private MarshallControlJpaController marshallJpa;

    private TomaMuestraHormigon tmh = null;
    private TomaMuestraHormigonJpaController tmhJpa;

    private List<NroMoldes> nromoldes = null;
    private NroMoldesJpaController nromoldesJpa;

    private AntecedentesHormigon antehorm = null;
    private AntecedentesHormigonJpaController antehormJpa;

    private List<MaterialesHormigon> mathorm = null;
    private MaterialesHormigonJpaController mathormJpa;

    private List<RupturaMoldes> rupmoldes = null;
    private RupturaMoldesJpaController rupmoldesJpa;

    String selectedEnsayo, Area;

    public SelectItem[] getFormularioItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(jpaController.findFormularioEntities(), false);
    }

    public SelectItem[] getFormularioItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(jpaController.findFormularioEntities(), true);
    }

    public SelectItem[] getNroMoldesItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(this.nromoldes, false);
    }

    public Formulario getFormulario() {
        if (formulario == null) {
            formulario = (Formulario) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentFormulario", converter, null);
        }
        if (formulario == null) {
            formulario = new Formulario();
        }
        return formulario;
    }

    public ControlTemperatura getCtemp() {
        return ctemp;
    }

    public void setCtemp(ControlTemperatura ctemp) {
        this.ctemp = ctemp;
    }

    public List<MedicionesCTR> getMedCtr() {
        medCtr = medCtrJpa.findMedicionesDCAsById(ctr.getId());
        return medCtr;
    }

    public void setMedCtr(List<MedicionesCTR> medCtr) {
        this.medCtr = medCtr;
    }

    public ControlTasaRiego getCtr() {
        return ctr;
    }

    public void setCtr(ControlTasaRiego ctr) {
        this.ctr = ctr;
    }

    public List<PuntoDCAr> getPuntoDCAr() {
        puntoDCAr = puntoDCArJpa.findPuntoDCArById(dcarena.getId());
        return puntoDCAr;
    }

    public void setPuntoDCAr(List<PuntoDCAr> puntoDCAr) {
        this.puntoDCAr = puntoDCAr;
    }

    public List<InformeReferenciaDCAr> getInfRefDCAr() {
        infRefDCAr = infRefDCArJpa.findInformeReferenciaDCArById(dcarena.getId());
        return infRefDCAr;
    }

    public void setInfRefDCAr(List<InformeReferenciaDCAr> infRefDCAr) {
        this.infRefDCAr = infRefDCAr;
    }

    public List<MedicionesDCAs> getMedDcasf() {
        medDcasf = medDcasfJpa.findMedicionesDCAsById(dcasf.getId());
        return medDcasf;
    }

    public void setMedDcasf(List<MedicionesDCAs> medDcasf) {
        this.medDcasf = medDcasf;
    }

    public List<MedicionesCT> getMedCT() {
        medCT = medCTJpa.findMedicionesCTById(ctemp.getId());
        return medCT;
    }

    public void setMedCT(List<MedicionesCT> medCT) {
        this.medCT = medCT;
    }

    public DensidadesConoArena getDcarena() {
        return dcarena;
    }

    public void setDcarena(DensidadesConoArena dcarena) {
        this.dcarena = dcarena;
    }

    public DensidadesCarpetaAsfaltica getDcasf() {
        return dcasf;
    }

    public void setDcasf(DensidadesCarpetaAsfaltica dcasf) {
        this.dcasf = dcasf;
    }

    public Hilo getHilo() {
        return hilo;
    }

    public void setHilo(Hilo hilo) {
        this.hilo = hilo;
    }

    public List<MedicionesHilo> getMedHilo() {
        medHilo = medHiloJpa.findMedicionesHiloById(hilo.getId());
        return medHilo;
    }

    public void setMedHilo(List<MedicionesHilo> medHilo) {
        this.medHilo = medHilo;
    }

    public MarshallControl getMarshall() {
        return marshall;
    }

    public void setMarshall(MarshallControl marshall) {
        this.marshall = marshall;
    }

    public TomaMuestraHormigon getTmh() {
        return tmh;
    }

    public void setTmh(TomaMuestraHormigon tmh) {
        this.tmh = tmh;
    }

    public AntecedentesHormigon getAntehorm() {
        return antehorm;
    }

    public void setAntehorm(AntecedentesHormigon antehorm) {
        this.antehorm = antehorm;
    }

    public List<MaterialesHormigon> getMathorm() {
        return mathorm;
    }

    public void setMathorm(List<MaterialesHormigon> mathorm) {
        this.mathorm = mathorm;
    }

    public List<NroMoldes> getNromoldes() {
        return nromoldes;
    }

    public void setNromoldes(List<NroMoldes> nromoldes) {
        this.nromoldes = nromoldes;
    }

    public List<RupturaMoldes> getRupmoldes() {
        return rupmoldes;
    }

    public void setRupmoldes(List<RupturaMoldes> rupmoldes) {
        this.rupmoldes = rupmoldes;
    }

    public TomaMuestraSuelo getTms() {
        return tms;
    }

    public void setTms(TomaMuestraSuelo tms) {
        this.tms = tms;
    }

    public DensidadesConDensimetro getDcd() {
        return dcd;
    }

    public void setDcd(DensidadesConDensimetro dcd) {
        this.dcd = dcd;
    }

    public List<InformeReferenciaDCD> getInfDcd() {
        return infDcd;
    }

    public void setInfDcd(List<InformeReferenciaDCD> infDcd) {
        this.infDcd = infDcd;
    }

    public List<PuntoDCD> getPuntoDcd() {
        return puntoDcd;
    }

    public void setPuntoDcd(List<PuntoDCD> puntoDcd) {
        this.puntoDcd = puntoDcd;
    }

    public String getSelectedEnsayo() {
        return this.selectedEnsayo;
    }

    public void setSelectedEnsayo(String SelectedEnsayo) {
        this.selectedEnsayo = SelectedEnsayo;
    }

    public String getArea() {
        return this.Area;
    }

    public void areaChange(ValueChangeEvent event) {
        String newValue = event.getNewValue().toString();
        Ensayos.clear();
        if (newValue.equals("Asfalto")) {
            Ensayos.add(new SelectItem("noseleccionado","(no seleccionado)"));
            Ensayos.add(new SelectItem("031", "Marshall de control"));
            Ensayos.add(new SelectItem("043", "Densidades carpeta asfáltica"));
            Ensayos.add(new SelectItem("057", "Control temperatura"));
            Ensayos.add(new SelectItem("065", "Control tasa de riego"));
            Ensayos.add(new SelectItem("073", "Muestreo asfalto"));
            Ensayos.add(new SelectItem("087", "Hi-Lo"));
        } else if (newValue.equals("Suelos")) {
            Ensayos.add(new SelectItem("noseleccionado","(no seleccionado)"));
            Ensayos.add(new SelectItem("019", "Densidades con densímetro"));
            Ensayos.add(new SelectItem("00S", "Toma de muestra de suelo"));
        } else if (newValue.equals("Hormigones")) {
            Ensayos.add(new SelectItem("noseleccionado","(no seleccionado)"));
            Ensayos.add(new SelectItem("010", "Toma de muestra de hormigón"));

        }else {
            //JOptionPane.showMessageDialog(null, event.getNewValue());
        }
    }

    public void setArea(String area) {
        this.Area = area;
    }

    public List getEnsayos() {
        if (Ensayos == null) {
            Ensayos = new ArrayList();
        }
        return Ensayos;
    }

    public String listSetup() {
        reset(true);
        return "formulario_list";
    }

    public String createSetup() {
        reset(false);
        formulario = new Formulario();
        return "formulario_create";
    }

    public String create() {
        try {
            jpaController.create(formulario);
            JsfUtil.addSuccessMessage("Formulario was successfully created.");
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "A persistence error occurred.");
            return null;
        }
        return listSetup();
    }

    public String detailSetup() {
        return scalarSetup("formulario_detail");
    }

    public String editSetup() {
        return scalarSetup("formulario_edit");
    }

    public String searchSetup() {
        OrdenDeTrabajo o = new OrdenDeTrabajo();
        getFormulario().setNroOT(o);
        this.Area = "noseleccionado";
        this.selectedEnsayo = null;
        getEnsayos().clear();
        return "formulario_search";
    }

    private String scalarSetup(String destination) {
        reset(false);
        formulario = (Formulario) JsfUtil.getObjectFromRequestParameter("jsfcrud.currentFormulario", converter, null);
        if (formulario == null) {
            String requestFormularioString = JsfUtil.getRequestParameter("jsfcrud.currentFormulario");
            JsfUtil.addErrorMessage("The formulario with id " + requestFormularioString + " no longer exists.");
            return relatedOrListOutcome();
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("019")){
            dcd = dcdJpa.findDensidadesConDensimetro(formulario.getId());
            infDcd = infDcdJpa.findInformeReferenciaDCDByNroId(dcd.getId());
            puntoDcd = puntoDcdJpa.findPuntoDCDByNroId(dcd.getId());
            return "densidadesConDensimetro_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("00S")){
            tms = tmsJpa.findTomaMuestraSuelo(formulario.getId());
            return "tomaMuestraSuelo_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("073")){
            masf = masfJpa.findMuestreoAsfalto(formulario.getId());
            return "muestreoAsfalto_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("031")){
            marshall = marshallJpa.findMarshallControl(formulario.getId());
            return "marshallControl_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("043")){
            dcasf = dcasfJpa.findDensidadesCarpetaAsfaltica(formulario.getId());
            return "densidadesCarpetaAsfaltica_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("057")){
            ctemp = ctempJpa.findControlTemperatura(formulario.getId());
            return "controlTemperatura_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("065")){
            ctr = ctrJpa.findControlTasaRiego(formulario.getId());
            return "controlTasaRiego_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("087")){
            hilo = hiloJpa.findHilo(formulario.getId());
            return "hilo_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("010")){
            tmh = tmhJpa.findTomaMuestraHormigon(formulario.getId());
            antehorm = antehormJpa.findAntecedentesHormigon(tmh.getId());
            mathorm = mathormJpa.findMaterialesHormigonById(tmh.getId());
            rupmoldes = rupmoldesJpa.findRupturaMoldesById(tmh.getId());
            nromoldes = nromoldesJpa.findNroMoldesById(tmh.getId());
            return "tomaMuestraHormigon_detail";
        }
        else if(formulario.getCodigoEnsayo().getCodigoEnsayo().equals("092")){
            dcarena = dcarenaJpa.findDensidadesConoArena(formulario.getId());
            return "densidadesConoArena_detail";
        }

        return destination;
    }

    public String edit() {
        String formularioString = converter.getAsString(FacesContext.getCurrentInstance(), null, formulario);
        String currentFormularioString = JsfUtil.getRequestParameter("jsfcrud.currentFormulario");
        if (formularioString == null || formularioString.length() == 0 || !formularioString.equals(currentFormularioString)) {
            String outcome = editSetup();
            if ("formulario_edit".equals(outcome)) {
                JsfUtil.addErrorMessage("No se pudo editar el formulario. Por favor intente de nuevo.");
            }
            return outcome;
        }
        try {
            jpaController.edit(formulario);
            JsfUtil.addSuccessMessage("Formulario actualizado exitosamente.");
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return listSetup();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "Ocurrió un error al intentar editar el formulario.");
            return null;
        }
        return detailSetup();
    }

    public MuestreoAsfalto getMasf() {
        return masf;
    }

    public void setMasf(MuestreoAsfalto masf) {
        this.masf = masf;
    }

    public String destroy() {
        String idAsString = JsfUtil.getRequestParameter("jsfcrud.currentFormulario");
        Integer id = new Integer(idAsString);
        try {
            jpaController.destroy(id);
            JsfUtil.addSuccessMessage("El formuario se ha eliminado exitosamente.");
        } catch (NonexistentEntityException ne) {
            JsfUtil.addErrorMessage(ne.getLocalizedMessage());
            return relatedOrListOutcome();
        } catch (Exception e) {
            JsfUtil.ensureAddErrorMessage(e, "Ocurrió un error al intentar eliminar el formulario.");
            return null;
        }
        return relatedOrListOutcome();
    }

    private String relatedOrListOutcome() {
        String relatedControllerOutcome = relatedControllerOutcome();
        if (relatedControllerOutcome != null) {
            return relatedControllerOutcome;
        }
        return listSetup();
    }

    public List<Formulario> getFormularioItems() {
        if (formularioItems == null) {
            //getPagingInfo();
            formularioItems = jpaController.findFormularioEntities();
        }
        return formularioItems;
    }

    public String search(){
        actualizarFormularios(true);
        return "formulario_list";
    }

    private void actualizarFormularios(boolean reset){
        if(formulario.getNroOT() != null){
            formularioItems = jpaController.findFormularioByNroOT(formulario.getNroOT());
        }else if(this.selectedEnsayo != null && !this.selectedEnsayo.equals("noseleccionado")){
            formularioItems = jpaController.findFormularioByCodigoEnsayo(this.selectedEnsayo);
        }else if(!this.Area.equals("noseleccionado")){
            formularioItems = jpaController.findFormularioByArea(this.Area);
        }else{
            formularioItems = jpaController.findFormularioEntities(jpaController.getFormularioCount(), 0);
        }
        //reset(reset, true);
        //getPagingInfo();
        //formularioItems = formularioTotal.subList(getPagingInfo().getFirstItem(), getPagingInfo().getLastItem());
    }

    private String relatedControllerOutcome() {
        String relatedControllerString = JsfUtil.getRequestParameter("jsfcrud.relatedController");
        String relatedControllerTypeString = JsfUtil.getRequestParameter("jsfcrud.relatedControllerType");
        if (relatedControllerString != null && relatedControllerTypeString != null) {
            FacesContext context = FacesContext.getCurrentInstance();
            Object relatedController = context.getApplication().getELResolver().getValue(context.getELContext(), null, relatedControllerString);
            try {
                Class<?> relatedControllerType = Class.forName(relatedControllerTypeString);
                Method detailSetupMethod = relatedControllerType.getMethod("detailSetup");
                return (String) detailSetupMethod.invoke(relatedController);
            } catch (ClassNotFoundException e) {
                throw new FacesException(e);
            } catch (NoSuchMethodException e) {
                throw new FacesException(e);
            } catch (IllegalAccessException e) {
                throw new FacesException(e);
            } catch (InvocationTargetException e) {
                throw new FacesException(e);
            }
        }
        return null;
    }

    private void reset(boolean resetFirstItem) {
        formulario = null;
        formularioItems = null;
    }

    public void validateCreate(FacesContext facesContext, UIComponent component, Object value) {
        Formulario newFormulario = new Formulario();
        String newFormularioString = converter.getAsString(FacesContext.getCurrentInstance(), null, newFormulario);
        String formularioString = converter.getAsString(FacesContext.getCurrentInstance(), null, formulario);
        if (!newFormularioString.equals(formularioString)) {
            createSetup();
        }
    }

    public void validateNroOT(FacesContext facesContext, UIComponent component, Object value){
        boolean b = Pattern.matches("[0-9]{2,11}", value.toString());
        if(!b){
            FacesMessage fm = new FacesMessage(FacesMessage.SEVERITY_ERROR, "El n° de OT no es válido. Debe contener 2-11 dígitos.", null);
            facesContext.addMessage(null, fm);
            throw new ValidatorException(fm);
        }
    }

    public Converter getConverter() {
        return converter;
    }

}
